#coding='utf8'

class _crc32(object):
    def __init__(self, s=''):
        import zlib
        self.crc32 = zlib.crc32
        self.crc = self.crc32(s)
    def update(self, s):
        self.crc = self.crc32(s, self.crc)
    def hexdigest(self):
        import struct
        return hex(struct.unpack('L', struct.pack('l', self.crc))[0])[2:10]

def default_checksum_func(filename, checksum_type, checksum_value):
    message = u"%s ( %s: %s )" % (filename, checksum_type, checksum_value)
    print message

def checksum(filename, checksum_func=default_checksum_func, message_func=None, buffer_size=1024*1024*16):
    import os
    if not os.path.isfile(filename):
        print '%s is not a file.' % filename
        return
    import hashlib
    _map = {}
    _map['MD5'] = hashlib.md5()
    _map['SHA1'] = hashlib.sha1()
    _map['CRC32'] = _crc32()
    total_size = os.path.getsize(filename)
    process_size = 0
    if message_func:
        message_func(filename, process_size, total_size)
    f = open(filename, 'rb')
    d = f.read(buffer_size)
    while d:
        for o in _map.values():
            o.update(d)
        process_size += len(d)
        if message_func:
            message_func(filename, process_size, total_size)
        d = f.read(buffer_size)
    for k, v in _map.iteritems():
        checksum_func(filename, k, v.hexdigest().upper())

if __name__ == '__main__':
    import sys
    import os
    if len(sys.argv) == 1:
        for filename in os.listdir('.'):
            if os.path.isfile(filename):
                checksum(filename)
    else:
        for filename in sys.argv[1:]:
            if os.path.isfile(filename):
                checksum(filename)
